package com.umessage.system.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.umessage.common.service.impl.BaseService;
import com.umessage.common.util.MD5Utils;
import com.umessage.hotel.domain.Coupon;
import com.umessage.system.dao.UserMapper;
import com.umessage.system.dao.UserRoleMapper;
import com.umessage.system.domain.User;
import com.umessage.system.domain.UserRole;
import com.umessage.system.domain.UserWithRole;
import com.umessage.system.service.UserRoleService;
import com.umessage.system.service.UserService;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

@Service("userService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class UserServiceImpl extends BaseService<User> implements UserService {

	@Autowired
	private UserMapper userMapper;

	@Autowired
	private UserRoleMapper userRoleMapper;

	@Autowired
	private UserRoleService userRoleService;

	@Override
	public User findByName(String userName) {
		Example example = new Example(User.class);
		example.createCriteria().andCondition("lower(username)=", userName.toLowerCase());
		List<User> list = this.selectByExample(example);
		return list.size() == 0 ? null : list.get(0);
	}

	@Override
	public List<User> findUserWithDept(User user) {
		try {
			return this.userMapper.findUserWithDept(user);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<>();
		}
	}

	@Override
	public List<User> findUserWithHotel(User user) {
		try {
			return this.userMapper.findUserWithHotel(user);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<>();
		}
	}

	@Override
	@Transactional
	public void registUser(User user) {
		user.setCrateTime(new Date());
		user.setTheme(User.DEFAULT_THEME);
		user.setAvatar(User.DEFAULT_AVATAR);
		user.setSsex(User.SEX_UNKNOW);
		user.setPassword(MD5Utils.encrypt(user.getUsername(), user.getPassword()));
		this.save(user);
		UserRole ur = new UserRole();
		ur.setUserId(user.getUserId());
		ur.setRoleId(3L);
		this.userRoleMapper.insert(ur);
	}

	@Override
	@Transactional
	public void updateTheme(String theme, String userName) {
		Example example = new Example(User.class);
		example.createCriteria().andCondition("username=", userName);
		User user = new User();
		user.setTheme(theme);
		this.userMapper.updateByExampleSelective(user, example);
	}

	@Override
	@Transactional
	public void addUser(User user, Long[] roles) {
		/**
		 * 用于区分酒店员工和酒店超级管理员
		 * 1  酒店超级管理员
		 * 0  酒店员工
		 */
		user.setDeptId(1l);
		user.setCrateTime(new Date());
		user.setTheme(User.DEFAULT_THEME);
		user.setAvatar(User.DEFAULT_AVATAR);
		user.setPassword(MD5Utils.encrypt(user.getUsername(), user.getPassword()));
		this.save(user);
		setUserRoles(user, roles);
	}
	
	@Override
	@Transactional
	public void addUserAndRoleNull(User user, Long[] roles) {
		user.setCrateTime(new Date());
		user.setTheme(User.DEFAULT_THEME);
		user.setAvatar(User.DEFAULT_AVATAR);
		user.setPassword(MD5Utils.encrypt(user.getMobile(), user.getPassword()));
		this.save(user);
		if(roles!=null) {
			setUserRoles(user, roles);
		}
	}

	private void setUserRoles(User user, Long[] roles) {
		Arrays.stream(roles).forEach(roleId -> {
			UserRole ur = new UserRole();
			ur.setUserId(user.getUserId());
			ur.setRoleId(roleId);
			this.userRoleMapper.insert(ur);
		});
	}

	@Override
	@Transactional
	public void updateUser(User user, Long[] roles) {
		user.setPassword(null);
		user.setUsername(null);
		user.setModifyTime(new Date());
		this.updateNotNull(user);
		Example example = new Example(UserRole.class);
		example.createCriteria().andCondition("user_id=", user.getUserId());
		this.userRoleMapper.deleteByExample(example);
		setUserRoles(user, roles);
	}
	@Override
	@Transactional
	public void updateUserAndRoleNull(User user, Long[] roles) {
		user.setPassword(null);
		user.setUsername(null);
		user.setModifyTime(new Date());
		this.updateNotNull(user);
		Example example = new Example(UserRole.class);
		example.createCriteria().andCondition("user_id=", user.getUserId());
		this.userRoleMapper.deleteByExample(example);
		if(roles!=null) {
			setUserRoles(user, roles);
		}
	}

	@Override
	@Transactional
	public void deleteUsers(String userIds) {
		List<String> list = Arrays.asList(userIds.split(","));
		this.batchDelete(list, "userId", User.class);

		this.userRoleService.deleteUserRolesByUserId(userIds);
	}

	@Override
	@Transactional
	public void updateLoginTime(String userName) {
		Example example = new Example(User.class);
		if(userName.length()<11) {
			example.createCriteria().andCondition("lower(username)=", userName.toLowerCase());
		}else {
			example.createCriteria().andCondition("lower(mobile)=", userName.toLowerCase());
		}
		
		User user = new User();
		user.setLastLoginTime(new Date());
		this.userMapper.updateByExampleSelective(user, example);
	}

	@Override
	@Transactional
	public void updatePassword(String password) {
		User user = (User) SecurityUtils.getSubject().getPrincipal();
		Example example = new Example(User.class);
		example.createCriteria().andCondition("username=", user.getUsername());
		String newPassword = MD5Utils.encrypt(user.getUsername().toLowerCase(), password);
		user.setPassword(newPassword);
		this.userMapper.updateByExampleSelective(user, example);
	}

	@Override
	public UserWithRole findById(Long userId) {
		List<UserWithRole> list = this.userMapper.findUserWithRole(userId);
		List<Long> roleList = new ArrayList<>();
		for (UserWithRole uwr : list) {
			roleList.add(uwr.getRoleId());
		}
		if (list.size() == 0) {
			return null;
		}
		UserWithRole userWithRole = list.get(0);
		userWithRole.setRoleIds(roleList);
		return userWithRole;
	}

	@Override
	public User findUserProfile(User user) {
		return this.userMapper.findUserProfile(user);
	}

	@Override
	@Transactional
	public void updateUserProfile(User user) {
		user.setUsername(null);
		user.setPassword(null);
		if (user.getDeptId() == null)
			user.setDeptId(0L);
		this.updateNotNull(user);
	}

	@Override
	public void addHotelAdminUser(User user) {
		user.setCrateTime(new Date());
		user.setTheme(User.DEFAULT_THEME);
		user.setAvatar(User.DEFAULT_AVATAR);
		user.setSsex(User.SEX_UNKNOW);
		user.setPassword(MD5Utils.encrypt(user.getUsername(), user.getPassword()));
		this.save(user);
		UserRole ur = new UserRole();
		ur.setUserId(user.getUserId());
		ur.setRoleId(4L);
		this.userRoleMapper.insert(ur);

	}

	@Override
	public User findUserByMobile(String hotelId, String mobile) {
		return userMapper.findUserByMobile(hotelId, mobile);
	}

	@Override
	public List<User> findUserByHotelId(User user) {
		try {
			Example example = new Example(User.class);
			Criteria createCriteria = example.createCriteria();
			if (user.getHotelId()!=null) {
				createCriteria.andCondition("hotel_id=", user.getHotelId());
			}
			if (StringUtils.isNotEmpty(user.getUsername())) {
				createCriteria.andCondition("username=", user.getUsername());
			}
			if (user.getUserId()!=null) {
				createCriteria.andCondition("user_id!=", user.getUserId());
			}
			createCriteria.andCondition("status=", 1);
			example.setOrderByClause("modify_Time desc,crate_Time desc");
			return this.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<>();
		}
	}

	@Override
	public User findUserByMobileNum(String mobile) {
		return userMapper.findUserByMobileNum(mobile);
	}

	@Override
	public User findUserByMobileAndHotel(String mobile, String hotelId) {
		Example example = new Example(User.class);
		Criteria createCriteria = example.createCriteria();
		if(StringUtils.isNotEmpty(mobile)) {
			createCriteria.andCondition("mobile=", mobile);
		}
		if(StringUtils.isNotEmpty(hotelId)) {
			createCriteria.andCondition("hotel_id=", hotelId);
		}
		List<User> list = this.selectByExample(example);
		return list.size() == 0 ? null : list.get(0);
	}

	@Override
	public User getUserByid(Long userId) {
		// TODO Auto-generated method stub
		return userMapper.getUserByid(userId);
	}

	@Override
	public List<User> findUserListByHotelId(String hotelId) {
		// TODO Auto-generated method stub
		return userMapper.findUserListByHotelId(hotelId);
	}

	@Override
	public List<String> findConfirmUserMobileList(String hotelId) {
		return userMapper.findConfirmUserMobileList(hotelId);
	}

	@Override
	public List<String> findMsgUserMobileList(String hotelId) {
		return userMapper.findMsgUserMobileList(hotelId);
	}
	/**
	 * 查找手机号是否被其他酒店使用
	 * 查询该手机号是否有其他可用信息
	 */
	@Override
	public User findUserByMobileAll(String mobile) {
		Example example = new Example(User.class);
		Criteria createCriteria = example.createCriteria();
		if(StringUtils.isNotEmpty(mobile)) {
			createCriteria.andCondition("mobile=", mobile);
		}
			createCriteria.andCondition("status=1");
		List<User> list = this.selectByExample(example);
		return list.size() == 0 ? null : list.get(0);
	}

}
